﻿using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//  vygenerovana .dll pridana ako referencia
using SIMcSDK;
using System.IO;
using System.Media;


namespace SIMc
{
    public partial class CallForm : Form
    {

        MainForm form1;
        public bool closed;
        public int sessionId;
        private Timer refreshTimer;
        public bool called;
        public string buddyURI;
        public SoundPlayer ringPlajer;

        enum pjsip_inv_state:int
        {
            PJSIP_INV_STATE_NULL=0, 
            PJSIP_INV_STATE_CALLING, 
            PJSIP_INV_STATE_INCOMING, 
            PJSIP_INV_STATE_EARLY,
            PJSIP_INV_STATE_CONNECTING, 
            PJSIP_INV_STATE_CONFIRMED, 
            PJSIP_INV_STATE_DISCONNECTED
        }

        public CallForm(MainForm form)
        {
            this.form1 = form;
            called = false;
            InitializeComponent();
            this.ringPlajer = new SoundPlayer(form.path + "Sounds\\ring.wav");
        }

        private void CallForm_Closed(object sender, EventArgs e)
        {
            closed = true;
        }

        private string getStateString(int state) {
            string status="";
            switch (state) { 
                case (int)pjsip_inv_state.PJSIP_INV_STATE_CALLING:
                    status = "Calling";
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED:
                    status = "Confirmed";
                    B_endCall.Enabled = true;
                    B_receive.Enabled = false;
                    B_hold.Enabled = true;
                    B_acceptCall.Enabled = false;
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_CONNECTING:
                    status = "Connecting";
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED:
                    status = "Disconnected";
                    ringPlajer.Stop();
                        B_endCall.Enabled = false;
                        B_receive.Enabled = false;
                        B_hold.Enabled = false;
                        B_acceptCall.Enabled = true;
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_EARLY:
                    status = "Ringing";
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_INCOMING:
                    status = "Incoming";
                    B_acceptCall.Enabled = true;
                    B_endCall.Enabled = true;
                    B_receive.Enabled = false;
                    B_hold.Enabled = false;
                    break;
                case (int)pjsip_inv_state.PJSIP_INV_STATE_NULL:
                    status = "Null";
                    break;
            }
            return status;
            
        }

        public void reakciaZmenaStavu(int callId, int callState)
        {
            if (closed == true)
            {
                //TB_buddy.Text = callId.ToString();

                TB_callState.Text = getStateString(callState);
                closed = false;
                this.ShowDialog();
            }
            else {
                //TB_buddy.Text = callId.ToString();
                TB_callState.Text = getStateString(callState);
            }
        }

        public void volaju(int callId, StringBuilder sturi)
        {
            if (closed == false)
            {
                CallControl.endCall(callId);
                return;
            }
            B_acceptCall.Text = "Accept call";
            B_acceptCall.Enabled = true;
            B_endCall.Enabled = true;
            B_receive.Enabled = false;
            B_hold.Enabled = false;
            this.closed = false;
            this.sessionId = callId;
            this.called = true;
            this.L_contact.Text = sturi.ToString();
            //form1.alerted(callId);
            if(!form1.MI_mute.Checked)
                ringPlajer.PlayLooping();
            CallControl.alerted(callId);
            this.ShowDialog();
        }

        private void UpdateCallTimeout(object sender, EventArgs e) {
            TB_duration.Text = (int.Parse(TB_duration.Text) + 1).ToString();
            //if (int.Parse(TB_duration.Text) > 60) {
            //    TB_duration.Text = "0";
            //    //form1.endCall(sessionId);
            //    CallControl.endCall(sessionId);
            //}
        }

        private void B_acceptCall_Click(object sender, EventArgs e)
        {
            B_acceptCall.Enabled = false;
            refreshTimer.Enabled = true;
            if (called)
            {
                ringPlajer.Stop();
                //TB_buddy.Text = sessionId.ToString();
                //form1.acceptCall(sessionId);
                CallControl.acceptCall(sessionId);
            }
            else
            {
                zavolaj(buddyURI, 2);
                //ked sa vymaze BULLSHIT, nahradit tymto
                //sessionId = CallControl.makeCall(buddyURI, 2);
                //TB_buddy.Text = sessionId.ToString();
            }
        }

        //  TODO: MODIFY
        //  toto je tu podla mna cele zbytocne
        //  ziadny delegat, ziadny event a dokonca ani invoke .. 
        //  podla mna staci zavolat v else klauzule vyssie toto: sessionId = CallControl.makeCall(buddyURI, 2);
        #region BULLSHIT
        public delegate int Zavolaj(string dialedNo, int accountID);
        public static event Zavolaj volaj;

        private int zavolaj(string dialedNo, int accountID)
        {
            if (form1.InvokeRequired)
            {
                //MessageBox.Show("bolo treba");
                this.BeginInvoke(new Zavolaj(form1.makeCall), new object[] { dialedNo, accountID });
            }
            else
            {
                //MessageBox.Show("nebolo treba");
                this.sessionId=form1.makeCall(dialedNo,accountID);
            }
            return 1;
        }
        #endregion BULLSHIT
        //public delegate void SpravaPrijata(string from, string message);
        //public static event SpravaPrijata prijataSprava;

        private void B_endCall_Click(object sender, EventArgs e)
        {
            B_endCall.Enabled = false;
            B_hold.Enabled = false;
            B_receive.Enabled = false;
            B_acceptCall.Enabled = true;
            CallControl.endCall(sessionId);
            //if(!form1.MI_mute.Checked)
                ringPlajer.Stop();
            //form1.endCall(sessionId);

            refreshTimer.Enabled = false;
            TB_duration.Text = "0";
            //this.Close();
        }

        private void CallForm_Activated(object sender, EventArgs e)
        {
            refreshTimer = new Timer();
            refreshTimer.Interval = 1000;
            refreshTimer.Tick += new EventHandler(UpdateCallTimeout);
            TB_duration.Text = "0";
            //refreshTimer.Enabled = true;
        }

        private void B_hold_Click(object sender, EventArgs e)
        {
            CallControl.holdCall(this.sessionId);
            B_hold.Enabled = false;
            B_receive.Enabled = true;
        }

        private void B_receive_Click(object sender, EventArgs e)
        {
            CallControl.retrieveCall(this.sessionId);
            B_receive.Enabled = false;
            B_hold.Enabled = true;
        }
    }
}